home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / System 7.0 Samples / AEObject-Edition1.0.2 Sample / Windows.c < prev   
Encoding:
C/C++ Source or Header  |  1994-11-18  |  67.4 KB  |  1,696 lines  |  [TEXT/MPS ]

  1. /*------------------------------------------------------------------------------
  2. *
  3. *  Apple Developer Technical Support
  4. *
  5. *  
  6. *
  7. *  Program: AEObject-Edition Sample
  8. *  File:   Windows.c -C Source
  9. *
  10. *  by: C.K. Haun <TR>
  11. *
  12. *  Copyright © 1990-1992 Apple Computer, Inc.
  13. *  All rights reserved.
  14. *
  15. *------------------------------------------------------------------------------
  16. * This file contains some of our window handling routines.   
  17. * It also contains the clipboard handlers
  18. *----------------------------------------------------------------------------*/
  19.  
  20. #define __MYWINDOWS__
  21.  
  22. #include "Sampdefines.h"
  23.  
  24. #pragma segment MyWindows
  25. static void DragPictOrObject(Point *where, windowCHandle tempWC);
  26.  
  27. /* AddNewWindow creates and initializes a new document window. */
  28. /* It returns false in this example if there are already 10 windows open. */
  29.  
  30. WindowPtr AddNewWindow(Boolean showIt)
  31. {
  32.     windowCHandle setControls;
  33.     WindowPtr tempWP;
  34.     Handle tempHand;
  35.     short cnt = 0;
  36.     Str31 wtitle;
  37.     tempWP = GetNewWindow(kDocWindow, 0, (WindowPtr)-1);        /* get a new window */
  38.     ((WindowPeek)tempWP)->windowKind = kDocumentWindow;     /* mark it as a document window */
  39.     tempHand = NewHandleClear(sizeof(windowControl));       /* add our control structure to it */
  40.     ((WindowPeek)tempWP)->refCon = tempHand;                /* and attach the controller to the window */
  41.     setControls = (windowCHandle)((WindowPeek)tempWP)->refCon;      /* and put it where we can use it */
  42.     HLock((Handle)setControls);                             /* lock it down while we fill it*/
  43.     
  44.     /* add pointers to our procedures for drawing, saving, and closing */
  45.     /* This way, all I need is one dispatch point for drawing, closing */
  46.     /* or whatever, I don't have to case off the window kind to go to the  */
  47.     /* correct routine.  Kinda like object-oriented programming, but I won't */
  48.     /* admit that. */
  49.     (*setControls)->drawMe = (ProcPtr)DrawFull;
  50.     (*setControls)->saveMe = (ProcPtr)SaveMe;
  51.     (*setControls)->closeMe = (ProcPtr)CloseMyWindow;
  52.     (*setControls)->clickMe = (ProcPtr)DoDocumentClick;
  53.     (*setControls)->sizeMe = (ProcPtr)NilProc;
  54.     /* now initialize all our required handles */
  55.     (*setControls)->pubs = NewHandle(0);
  56.     (*setControls)->pubRects = NewHandle(0);
  57.     (*setControls)->numPubs = 0;
  58.     (*setControls)->subs = NewHandle(0);
  59.     (*setControls)->subRects = NewHandle(0);
  60.     (*setControls)->subDataHandle = NewHandle(0);
  61.     (*setControls)->numSubs = 0;
  62.     (*setControls)->pictHandle = NewHandle(0);
  63.     (*setControls)->pictRects = NewHandle(0);
  64.     (*setControls)->numPicts = 0;
  65.     /* init shapes */
  66.     (*setControls)->theShapes = nil;
  67.     (*setControls)->numShapes = 0;
  68.     /* initialize our control codes and counts */
  69.     (*setControls)->currentAction = 0;
  70.     (*setControls)->undoAction = 0;
  71.     (*setControls)->hasSelection = false;
  72.     (*setControls)->windowDirty = false;
  73.     /* I am using this window ID to identify the sections (publishers and subscribers) */
  74.     /* that are associated with this window */
  75.     (*setControls)->windowID = gMasterWindowID;
  76.     gMasterWindowID += 10000;                               /* update for next window */
  77.     /* clear the file spec for the file this document will be saved to */
  78.     /* since the handle is nil, I know this window hasn't been saved yet. */
  79.     (*setControls)->fileAliasHandle = (AliasHandle)NewHandle(0);
  80.     (*setControls)->boxHandle = nil;                        /* no textedit field */
  81.     (*setControls)->textSections = nil;
  82.     /* if there already is a window (or more) add a count to this title */
  83.     if (showIt) {
  84.         short docWCount = 0;
  85.         WindowPtr ourWindows = (WindowPtr)LMGetWindowList();                   /* grab the first window from the global WindowList */
  86.         Str32 numOfW;
  87.         GetWTitle(tempWP, wtitle);                          /* get our current title (untitled) */
  88.         while (ourWindows) {                                /* count 'em up */
  89.             if (((WindowPeek)ourWindows)->windowKind == kDocumentWindow)
  90.                 docWCount++;                                /* only count doc windows o' course */
  91.             ourWindows = (WindowPtr)((WindowPeek)ourWindows)->nextWindow;
  92.         } /* end ourWindows while */
  93.         /* change the number to text, and append it */
  94.         NumToString((long)docWCount, numOfW);
  95.         AppendString(wtitle, numOfW);
  96.         SetWTitle(tempWP, wtitle);
  97.         ShowWindow(tempWP);                                 /* show it */
  98.     }
  99.     HUnlock((Handle)setControls);
  100.     SetPort(tempWP);
  101.     SetUndo(0, false);                                      /* since it is the current window, set all the actions to default */
  102.     SetCurAction(0);                                        /* initialize the environment for a new window in front */
  103.     SetMyCursor(0);
  104.     SwitchChecks(0);
  105.     SetWMenus(true);
  106.     if (showIt) {
  107.         /* add it's name to our window menu */
  108.         AddToWindowMenu(tempWP, nil);
  109.         ChangePlane(tempWP);
  110.     }
  111.     return(tempWP);
  112. }
  113.  
  114. /* end AddNewWindow */
  115.  
  116. /* CloseMyWindow closes the window and disposes of all the memory 
  117. *   associated with it.  It also calls HandleSections (sic) to UnRegister
  118. * all the editions associated with this window 
  119. */
  120.  
  121. void CloseMyWindow(WindowPtr theClose)
  122. {
  123.     windowCHandle theWind;
  124.     short alBack;
  125.     register qq;
  126.     OSErr myErr;
  127.     PicHandle *tempPicHandPtr;
  128.     NMRec myNotification;
  129.     Str255 nmWords;
  130.     myNotification.qType =nmType ;
  131.     myNotification.nmMark = nil;
  132.     myNotification.nmIcon = nil;
  133.     myNotification.nmSound = (Handle)-1;
  134.     myNotification.nmStr =&nmWords ;
  135.     myNotification.nmResp =nil ;
  136.  
  137.     theWind = (windowCHandle)GetWRefCon(theClose);
  138.     GetIndString(&nmWords,kGeneralStrings,kBringForward);
  139.     HLock((Handle)theWind);
  140.     /* First see if we need to ask the user if they want to save this window or not */
  141.     if ((*theWind)->windowDirty) {
  142.          ModalFilterUPP upp;
  143.        Str255 windName;
  144.         GetWTitle(theClose, windName);
  145.         ParamText(windName, "", "", "");
  146.         /* No before we can do this, we have to be the frontmost application.  It is */
  147.         /* not proper to put up a ModalDialog if you are not frontmost! */
  148.         /* But we cannot bully ourselves forward, we have got to  */
  149.         /* ask the AppleEvent Manager if we can come forward. */
  150.         /* •••• YOU MUST ASK TO COME FORWARD!!!!! */
  151.         /*  NEVER force yourself forward.  Bad thing will happen if you do, you will */
  152.         /* be messing up scripting systems if you change layers  */
  153.         /* at will.  So, we do this.... */
  154.             myErr = AEInteractWithUser(kAEDefaultTimeout, &myNotification, gCommonIdleFunctionUPP);
  155.         /* now we've got to check the error.  It is possible that there is NO way that */
  156.         /* we can come forward and bring up a dialog (imagine if this machine were running in another */
  157.         /* room, or late at night, and there was no-one to respond to the dialog) */
  158.         /* So we check like so.... */
  159.         if(myErr == errAENoUserInteraction){
  160.             return; /* we're blowing away the save because we can't talk about it */
  161.         }
  162.         InitCursor();
  163.         upp = NewModalFilterProc(standardAlertFilter);
  164.         alBack = Alert(kDirtyAlert, upp);                   /* Ask 'em */
  165.         DisposeRoutineDescriptor(upp);
  166.         
  167.         if (alBack == ok)                                   /* they said yes, dispatch to the save handler */
  168.             (ProcPtr)(*(theWind))->saveMe(theWind, theClose);
  169.         if (alBack == cancel) {
  170.             /* if they said Cancel, this also tells us that the user does not want to */
  171.             /* quit the application if they were in the midst of shutdown ops.  So, */
  172.             /* reset the stopping flag.  Even if they weren't, this doesn't do any harm */
  173.             gStop = false;
  174.             return;
  175.         }
  176.     }
  177.     /* Save all our subscribers and publishers */
  178.     HandleSectionSave(theWind, false, true, nil);
  179.     /* get rid of all our memory associated with this window */
  180.     DisposeHandle((*theWind)->pubs);
  181.     DisposeHandle((*theWind)->pubRects);
  182.     DisposeHandle((*theWind)->subs);
  183.     DisposeHandle((*theWind)->subRects);
  184.     DisposeHandle((Handle)(*theWind)->fileAliasHandle);
  185.     /* Was there a TextEdit handle??? */
  186.     if ((*theWind)->boxHandle != nil)
  187.         TEDispose((*theWind)->boxHandle);
  188.     /* if there are any pictures, kill them too */
  189.     if ((*theWind)->numPicts) {
  190.         HLock((*theWind)->pictHandle);
  191.         tempPicHandPtr = (PicHandle *)*(*theWind)->pictHandle;
  192.         for (qq = 0; qq < (*theWind)->numPicts; qq++) {     /* rectangles are handled in the HandleSectionSave */
  193.             KillPicture(*tempPicHandPtr);
  194.             tempPicHandPtr += 1;
  195.         }
  196.     }
  197.     DisposeHandle((*theWind)->pictHandle);
  198.     DisposeHandle((*theWind)->pictRects);
  199.     DisposeHandle((Handle)theWind);
  200.     DeleteFromWindowMenu(theClose);
  201.     /* and finally actually close the window */
  202.     CloseWindow(theClose);
  203.     if (FrontWindow()) {
  204.         gShowingSecHandle = nil;
  205.         gShowPub = false;
  206.         gShowSub = false;
  207.         if (((WindowPeek)FrontWindow())->windowKind == kDocumentWindow)
  208.             SetWMenus(true);
  209.     } else {
  210.         SetWMenus(false);
  211.         gShowingSecHandle = nil;
  212.         gShowPub = false;
  213.         gShowSub = false;
  214.     }
  215.     EnableItem(gFileMenuHandle, kOpenItem);
  216.     EnableItem(gFileMenuHandle, kNewItem);
  217.     
  218. } /* end CloseMyWindow */
  219.  
  220. /* DrawFull draws the contents of our document windows */
  221.  
  222. void DrawFull(windowCHandle theWind, WindowPtr theWindPtr)
  223. {
  224.     register qq;
  225.     Rect scratchRect;
  226.     RgnHandle tempRgn;
  227.     RGBColor black = {0,0,0};
  228.     Rect grabRect;
  229.     ShapesHandle theShape;
  230.     /* Are there any shapes in this window? */
  231.     if ((*theWind)->numShapes) {
  232.         theShape = (*theWind)->theShapes;
  233.         /* walk through all the shapes */
  234.         do {
  235.             HLock((Handle)theShape);
  236.             switch ((*theShape)->type) {
  237.                 /* Draw whatever type of shape this is */
  238.                 case kLineShape:
  239.                      if(gHasColor)
  240.                         RGBForeColor(&(*theShape)->theColor);                        
  241.                     MoveTo((*theShape)->theRect.left, (*theShape)->theRect.top);
  242.                     LineTo((*theShape)->theRect.right, (*theShape)->theRect.bottom);
  243.                     break;
  244.                 case kRectShape:
  245.                      if(gHasColor)
  246.                         RGBForeColor(&(*theShape)->theColor);                        
  247.                     FrameRect(&(*theShape)->theRect);
  248.                     break;
  249.                 case kOvalShape:
  250.                     if(gHasColor)
  251.                         RGBForeColor(&(*theShape)->theColor);                        
  252.                     FrameOval(&(*theShape)->theRect);
  253.                     break;
  254.             }
  255.             HUnlock((Handle)theShape);
  256.             theShape = (*theShape)->nextShape;
  257.         }while (theShape); /* end of shape list */
  258.     }
  259. if(gHasColor)
  260.     RGBForeColor(&black);                        
  261.     
  262.     /* Is there a TextEdit field in this window? */
  263.     if ((*theWind)->boxHandle != nil) {
  264.         /* If there is a textedit field, there may also be bordered text sections, */
  265.         /* so check for them also */
  266.         Rect framer;
  267.         mySectionDataHandle tempTS = (*theWind)->textSections;
  268.         TEUpdate(&(*theWind)->textBox, (*theWind)->boxHandle);
  269.         framer = (*theWind)->textBox;
  270.         InsetRect(&framer, -3, -2);
  271.         FrameRect(&framer);
  272.         /* step through any possible sections, and border them as needful */
  273.         while (tempTS) {
  274.             if ((*tempTS)->bordered)
  275.                 BorderTextSection(tempTS);
  276.             tempTS = (*tempTS)->nextSection;
  277.         } /* end of text section list check */
  278.     }
  279.     
  280.     if ((*theWind)->numSubs) {                              /* are we subscribed to anything? */
  281.         PicHandle *tempHand;
  282.         Handle *tempRHand;
  283.         Rect *tempRect;
  284.         HLock((*theWind)->subDataHandle);                   /* lock down and get the rectangles and */
  285.         HLock((*theWind)->subRects);                        /* current picture data for the subscribers this */
  286.         tempHand = (PicHandle *)*(*theWind)->subDataHandle;     /* window has */
  287.         tempRHand = (Handle *)*(*theWind)->subRects;
  288.         /* cast them into a handy form, and step through the list, drawing each */
  289.         for (qq = 0; qq < (*theWind)->numSubs; qq++) {
  290.             PicHandle tempPic;
  291.             tempPic = *tempHand;
  292.             /* ••••This following check is important!•••• */
  293.             /* No matter what data type you are subscribing to, the data MAY NOT */
  294.             /* be in your application at the time you get an update.  */
  295.             /* Updates have a higher event priority than AppleEvents, and you usually */
  296.             /* will get an update event after you show the 'Subscribe' dialog box and the */
  297.             /* user has subscribed to something.  */
  298.             /* What that means is that you may not have yet gotten the first Section Read */
  299.             /* event for this subscription, you have no data to display. */
  300.             if (GetHandleSize((Handle)tempPic) != nil) {
  301.                 HLock(*tempRHand);
  302.                 tempRect = (Rect *)*(*tempRHand);
  303.                 DrawPicture(tempPic, tempRect);
  304.                 HUnlock(*tempRHand);
  305.             }
  306.             tempHand += 1;
  307.             tempRHand += 1;
  308.         }
  309.         HUnlock((*theWind)->subDataHandle);
  310.         HUnlock((*theWind)->subRects);
  311.     }
  312.     if ((*theWind)->numPicts) {
  313.         /* see if we have any pictures.  Pictures will be residual if the user */
  314.         /* used to have a subscriber, and canceled it.  We get rid of the subscription */
  315.         /* but keep the data */
  316.         Handle *tempPicPtr;
  317.         Handle *tempPicRect;
  318.         HLock((*theWind)->pictHandle);
  319.         HLock((*theWind)->pictRects);
  320.         tempPicPtr = (Handle *)*((*theWind)->pictHandle);
  321.         tempPicRect = (Handle *)*((*theWind)->pictRects);
  322.         for (qq = 0; qq < (*theWind)->numPicts; qq++) {
  323.             HLock(*tempPicRect);
  324.             DrawPicture((PicHandle)*tempPicPtr, (Rect *)(*(*tempPicRect)));
  325.             tempPicPtr += 1;
  326.             tempPicRect += 1;
  327.         }
  328.     }
  329.     /* Show publisher in this window if it's been clicked on lately */
  330.     if (theWindPtr == FrontWindow()) {
  331.         if (gShowPub) {
  332.             PenPat(&qd.gray);                                /* 50% gray for publishers */
  333.             PenSize(3, 3);
  334.             FrameRect(&gShowPubRect);
  335.             PenPat(&qd.black);
  336.             PenSize(1, 1);
  337.             grabRect = gShowPubRect;
  338.             grabRect.top = grabRect.bottom - 7;
  339.             grabRect.left = grabRect.right - 7;
  340.             PaintRect(&grabRect);
  341.             /* •••• NOTE:  I've taken the invert out of these areas because it got confusing for what */
  342.             /* I was publishing and subscribing.  Since we're dealing basically with bitmaps NOT */
  343.             /* with object-style graphiocs, the invert can be confusing.  */
  344.             /*   InsetRect(&gShowPubRect, 4, 4); */
  345.             /* invert the selection */
  346.             /*InvertRect(&gShowPubRect);*/
  347.             /*InsetRect(&gShowPubRect, -4, -4); */
  348.         }
  349.         if (gShowSub) {
  350.             PenPat(&qd.dkGray);                              /* 75% gray for subscriptions */
  351.             PenSize(3, 3);
  352.             InsetRect(&gShowSubRect, -4, -4);
  353.             FrameRect(&gShowSubRect);
  354.             
  355.             PenPat(&qd.black);
  356.             PenSize(1, 1);
  357.             /* same as NOTE above */
  358.             /*InsetRect(&gShowSubRect, 4, 4); */
  359.             /*InvertRect(&gShowSubRect); */
  360.             /*InsetRect(&gShowSubRect, -4, -4); */
  361.             /* add a resizing grabber */
  362.             if (gResizeSub) {
  363.                 /* If they can resize subscriptions, draw the grab box. */
  364.                 /* see the extra check box I added to the Subscriber Options dialog */
  365.                 grabRect = gShowSubRect;
  366.                 grabRect.top = grabRect.bottom - 7;
  367.                 grabRect.left = grabRect.right - 7;
  368.                 
  369.                 PenPat(&qd.black);
  370.                 /* if this is not the front window, just outline the grabber */
  371.                 /* if it is frontmost, draw it in solid black */
  372.                 if (theWindPtr != FrontWindow()) {
  373.                     EraseRect(&grabRect);
  374.                     FrameRect(&grabRect);
  375.                 } else {
  376.                     EraseRect(&grabRect);
  377.                     PaintRect(&grabRect);
  378.                 }
  379.             }
  380.             InsetRect(&gShowSubRect, 4, 4);
  381.         }
  382.         /* see if border showing is happening */
  383.         /* They optionally may have the 'Show All Borders' menu item checked, if so show */
  384.         /* the location of all the sections in this window */
  385.         if (gShowingAll) {
  386.             Rect borderRect;
  387.             /* show all pubs */
  388.             if ((*theWind)->numPubs) {
  389.                 Rect *tempRectPtr;
  390.                 HLock((*theWind)->pubRects);
  391.                 tempRectPtr = (Rect *)*(*theWind)->pubRects;
  392.                 PenPat(&qd.gray);                            /* 50% gray for publishers */
  393.                 PenSize(3, 3);
  394.                 for (qq = 0; qq < (*theWind)->numPubs; qq++) {
  395.                     borderRect = *tempRectPtr;
  396.                     FrameRect(&borderRect);
  397.                     tempRectPtr += 1;
  398.                 }
  399.                 HUnlock((*theWind)->pubRects);
  400.             }
  401.             
  402.             /* show all subs */
  403.             if ((*theWind)->numSubs) {
  404.                 
  405.                 Handle *theRectsHandle;
  406.                 
  407.                 HLock((*theWind)->subRects);                /* lock down the rect handle */
  408.                 /* cast it as a pointer to handles for reading ease */
  409.                 theRectsHandle = (Handle *)*(*theWind)->subRects;
  410.                 
  411.                 PenPat(&qd.dkGray);                          /* 75% gray for subscriptions */
  412.                 PenSize(3, 3);
  413.                 for (qq = 0; qq < (*theWind)->numSubs; qq++) {
  414.                     
  415.                     HLock(*theRectsHandle);
  416.                     
  417.                     borderRect = *((Rect *)*(*theRectsHandle));
  418.                     InsetRect(&borderRect, -4, -4);
  419.                     FrameRect(&borderRect);
  420.                     HUnlock(*theRectsHandle);
  421.                     theRectsHandle += 1;
  422.                     
  423.                 }
  424.                 HUnlock((*theWind)->subRects);
  425.                 
  426.             }
  427.             /* and show all text sections */
  428.             if ((*theWind)->textSections) {
  429.                 mySectionDataHandle tempTS = (*theWind)->textSections;
  430.                 do {
  431.                     BorderTextSection(tempTS);
  432.                     tempTS = (*tempTS)->nextSection;
  433.                 }while (tempTS);
  434.                 
  435.             }
  436.             PenSize(1, 1);
  437.             PenPat(&qd.black);
  438.         }
  439.     }
  440.     /* and the grow box */
  441.     scratchRect = theWindPtr->portRect;
  442.     scratchRect.top = scratchRect.bottom - 15;
  443.     scratchRect.left = scratchRect.right - 15;
  444.     tempRgn = NewRgn();
  445.     GetClip(tempRgn);
  446.     ClipRect(&scratchRect);
  447.     DrawGrowIcon(theWindPtr);
  448.     SetClip(tempRgn);
  449.     DisposeRgn(tempRgn);
  450.     
  451. }
  452.  
  453. /* end DrawFull */
  454.  
  455. /* DoDocumentClick handles clicking in the content region of our */
  456. /* document windows. */
  457. void DoDocumentClick(WindowPtr twindow)
  458. {
  459.     
  460.     /* if the window already was frontmost, take the right */
  461.     /* action for this window */
  462.     /* ••• NOTE: Normally, this is also the place where you would */
  463.     /* update the modification date (mdDate)  of publishers */
  464.     /* If the user takes an action across a published area, you */
  465.     /* should update the modification time to flag yourself that this */
  466.     /* edition needs to be sent.  This date/time will also show up in the */
  467.     /* Options dialog for that publisher. But for the sake of clarity in this */
  468.     /* sample, I am only changing the mod date on edition write (in files.c) */
  469.     Point endPoint;
  470.     Point oldendPoint;
  471.     Rect startRect;
  472.     Boolean wasInTB;
  473.     windowCHandle shortname;
  474.     short tempAct;
  475.     Rect testRect;
  476.     shortname = (windowCHandle)GetWRefCon(twindow);
  477.     /* This handle is already locked on entry, from the dispatcher that got us here */
  478.     
  479.     tempAct = (*shortname)->currentAction;                  /* what are they doing? */
  480.     SetPort(twindow);                                       /* make sure the port is good, I'm paranoid */
  481.     GlobalToLocal(&gERecord.where);                         /* everything will be in local coordinate to this window */
  482.     /* I don't want users to draw objects across my text box, so see if this click is in that thang */
  483.     testRect.left = testRect.right = gERecord.where.h;
  484.     testRect.right++;
  485.     testRect.top = testRect.bottom = gERecord.where.v;
  486.     testRect.bottom++;
  487.     wasInTB = InTextBox(shortname, &testRect);
  488.     if (!wasInTB || tempAct == kTextBox || tempAct == kNoAction) {
  489.         switch (tempAct) {                                  /* switch off the action code */
  490.             myLine tempLine;
  491.             case kNoAction:
  492.                 /* no menu items checked.  See if they clicked in a */
  493.                 /* publisher or subcriber */
  494.                 /* border a publisher or subscriber if they clicked in one */
  495.                 if (!SearchPubs(gERecord.where) && !SearchSubs(gERecord.where)) {
  496.                     /* if they didn't click in one, then erase the current selection */
  497.                     /* Check to see if they're clicking in the TERecord.  This takes precidence over */
  498.                     /* any other click */
  499.                     /* You'll want to change this depending on your app */
  500.                     if (wasInTB) {
  501.                         /* treat this like a random click to de-border any PICT subscriptions that */
  502.                         /* may be selected */
  503.                         KillSelection(shortname);
  504.                         DeBorderSelection();
  505.                         /* check publisher stuff here */
  506.                         
  507.                         TEClick(gERecord.where, gERecord.modifiers & shiftKey, (*shortname)->boxHandle);
  508.                         if (!gShowingAll) {
  509.                             mySectionDataHandle tempTS = (*shortname)->textSections;
  510.                             Boolean anyOn = false;          /* for our invalidate check */
  511.                             /* step through text sections and turn off flags */
  512.                             //while (tempTS) {
  513.                             ///* also check here to see if anything was bordered.  If it was, invalidate */
  514.                             ///* the TE rectangle so the old borders will be erased.  If there */
  515.                             ///* were NOT any, don't invalidate, so we don't strobe the user to */
  516.                             ///* blindness */
  517.                             //anyOn = anyOn | (*tempTS)->bordered;
  518.                             //(*tempTS)->bordered = false;
  519.                             //tempTS = (*tempTS)->nextSection;
  520.                             //}
  521.                             //if (anyOn)
  522.                             //InvalRect(&(*(*shortname)->boxHandle)->viewRect);
  523.                         }                                   /* see if the click was inside a subscriber */
  524.                         CheckSectionHit();
  525.                         
  526.                     } else {
  527.                         /* if it was a random click, dehilite the text selection if there is one */
  528.                         if ((*shortname)->boxHandle != nil) {
  529.                             TESetSelect((*(*shortname)->boxHandle)->selStart, (*(*shortname)->boxHandle)->selStart,
  530.                                         (*shortname)->boxHandle);
  531.                             /* Also, check to see if any borders are on in the TE box.  If so, turn them off.  */
  532.                             /* That is, unless gSHowingAll is on.... */
  533.                             /* and it's easiest just to invlaidate the terect */
  534.                             InvalRect(&(*(*shortname)->boxHandle)->viewRect);
  535.                             if (!gShowingAll) {
  536.                                 mySectionDataHandle tempTS = (*shortname)->textSections;
  537.                                 /* step through text sections and turn off flags */
  538.                                 while (tempTS) {
  539.                                     (*tempTS)->bordered = false;
  540.                                     tempTS = (*tempTS)->nextSection;
  541.                                 } /* tempTS while end */
  542.                             }
  543.                         }
  544.                         KillSelection(shortname);
  545.                         DeBorderSelection();
  546.                         /* and drag around a picture or an object if they want */
  547.                         DragPictOrObject(&gERecord.where, shortname);
  548.                     }
  549.                     break;
  550.                     case kDrawLine:
  551.                         /* they want to draw a line in this window */
  552.                         /* start and end points of the line set to the same val */
  553.                         oldendPoint = endPoint = gERecord.where;
  554.                         PenMode(srcXor);                    /* Xor so we can rubberband the line */
  555.                         while (StillDown()) {               /* Keep doing this as long as the */
  556.                             /* user keeps the mouse down */
  557.                             GetMouse(&endPoint);            /* Current mouse position in local */
  558.                             MakeRect(&gERecord.where, &endPoint, &testRect);
  559.                             if (!InTextBox(shortname, &testRect)) {
  560.                                 /* coordinates */
  561.                                 if (endPoint != oldendPoint) {      /* only do this if the mouse moved so the line doesn't flicker */
  562.                                     /* erase the old line (redraw in Xor mode ) */
  563.                                     MoveTo(gERecord.where.h, gERecord.where.v);
  564.                                     LineTo(oldendPoint.h, oldendPoint.v);
  565.                                     /* draw the new line */
  566.                                     MoveTo(gERecord.where.h, gERecord.where.v);
  567.                                     LineTo(endPoint.h, endPoint.v);
  568.                                     oldendPoint = endPoint;
  569.                                 }
  570.                             } else {
  571.                             endPoint = oldendPoint;
  572.                             }
  573.                         }  /* StillDown while end */
  574.                         PenMode(srcCopy);
  575.                         /* They released the mouse.  Add the line they drew */
  576.                         /* to our record */
  577.                         tempLine.start = gERecord.where;
  578.                         tempLine.end = endPoint;
  579.                         /* see this function later in this file */
  580.                         AddLine((windowCHandle)((WindowPeek)twindow)->refCon, &tempLine);
  581.                         /* changes the Undo menu item text */
  582.                         SetUndo(kDrawLine, false);
  583.                         break;                              /* end line case */
  584.                         
  585.                         /* they want to draw a rectangle in this window */
  586.                     case kDrawRect:
  587.                         /* start and end of rectangle set to the same val */
  588.                         PullRect(shortname, &startRect, false, false, true);
  589.                         /* Add it to our window */
  590.                         AddRect((windowCHandle)((WindowPeek)twindow)->refCon, &startRect);
  591.                         SetUndo(kDrawRect, false);          /* Set undo menu item text to */
  592.                         /* Undo Rectangle */
  593.                         break;                              /* end rectangle case */
  594.                         
  595.                     case kDrawOval:
  596.                         /* start and end of oval set to the same val */
  597.                         PullRect(shortname, &startRect, true, false, true);
  598.                         /* Add the oval to our window struct */
  599.                         AddOval((windowCHandle)((WindowPeek)twindow)->refCon, &startRect);
  600.                         /* Set undo menu item text to Undo Oval */
  601.                         SetUndo(kDrawOval, false);
  602.                         break;
  603.                     case kTextBox:
  604.                         /* start and end of rectangle set to the same val */
  605.                         PullRect(shortname, &startRect, false, false, true);
  606.                         /* Add it to our window */
  607.                         AddTextBox((windowCHandle)((WindowPeek)twindow)->refCon, &startRect);
  608.                         SetUndo(kCantUndo, false);          /* can't undo a text box */
  609.                         SwitchChecks(kTextBox);
  610.                         InitCursor();
  611.                         /* Undo Rectangle */
  612.                         break;
  613.                     case kSelectStuff:
  614.                         /* pretty much like drawrect, but */
  615.                         /* the resulting rect can be published */
  616.                         /* get rid of the old one */
  617.                         if ((*shortname)->hasSelection)        
  618.                             KillSelection((windowCHandle)GetWRefCon(twindow));
  619.                         PullRect(shortname, &startRect, false, false, true);
  620.                         PenPat(&qd.gray);
  621.                         FrameRect(&startRect);
  622.                         PenPat(&qd.black);
  623.                         PenSize(1, 1);
  624.                         AddSelection((windowCHandle)((WindowPeek)twindow)->refCon, &startRect);
  625.                         /* they can only select one rectangle, so clear the check */
  626.                         /* and change the cursor back to an arrow */
  627.                         SwitchChecks(kSelectStuff);
  628.                         InitCursor();
  629.                         (*shortname)->hasSelection = true;
  630.                         SetUndo(kSelectItem - 1, false);        /* since the item on the menu is one more than our use, because of the divider */
  631.                         /* before the MenuSelect call above to see how it's used */
  632.                         break;
  633.                         break;
  634.                 } else {
  635.                     unsigned long timeNow;
  636.                     /* they did click in one, see if it is/was a double click please */
  637.                     /* A double-click in a section should be treated the same */
  638.                     /* as if the user had selected Pub/Sub options for that section */
  639.                     KillSelection(shortname);
  640.                     if ((gShowingSecHandle == gLastSection) && (gShowingSecHandle != nil)) {
  641.                         timeNow = TickCount();
  642.                         if ((timeNow - gLastSecClickTick) < GetDblTime()) {
  643.                             /* it is a double click.  treat the same way as the menu selection for */
  644.                             /* Options UNLESS they had the option key down, then do a gotopublisher*/
  645.                             if (gERecord.modifiers & optionKey)
  646.                                 MyGoToPublisher(gLastSection);
  647.                             else
  648.                                 DoOptions(gShowingSecHandle);       /* in Subscribe.c. */
  649.                             
  650.                         } else {
  651.                             /* not a double click.  Set up for the next pass */
  652.                             /* de-border the old one please */
  653.                             gLastSecClickTick = timeNow;
  654.                             gLastSection = gShowingSecHandle;
  655.                         }
  656.                     } else {
  657.                         gLastSecClickTick = timeNow;
  658.                         gLastSection = gShowingSecHandle;
  659.                     }
  660.                 }
  661.         }
  662.     } else {
  663.     /* no matter which tool is selected, you can select in the TB */
  664.     TEClick(gERecord.where, gERecord.modifiers & shiftKey, (*shortname)->boxHandle);
  665.     }
  666. }
  667.  
  668. /* end DoDocumentClick */
  669.  
  670. /* DragPictOrObject drags a shape or picture.  Stores last position in */
  671. /* window structure for Undo */
  672. void DragPictOrObject(Point *where, windowCHandle tempWC)
  673. {
  674.     Handle *tempPicRect;
  675.     ShapesHandle theShapes;
  676.     register qq;
  677.     Rect origRect;
  678.     Boolean hadIt = false;
  679.     Point thePoint;
  680.     /* See if the hit was in a Pict, search all picts  */
  681.     
  682.     if ((*tempWC)->numPicts) {
  683.         HLock((*tempWC)->pictRects);
  684.         
  685.         tempPicRect = (Handle *)*((*tempWC)->pictRects);
  686.         /* run through all of them */
  687.         for (qq = 0; qq < (*tempWC)->numPicts; qq++) {
  688.             /* Did we hit this one? */
  689.             if (PtInRect(*where, (Rect *)(*(*tempPicRect)))) {
  690.             /* Yes, drag it around */            
  691.                 Rect dragger = *((Rect *)(*(*tempPicRect)));
  692.                 thePoint = *where;
  693.                 origRect = dragger;
  694.                 hadIt = true;
  695.                 PullRect(tempWC, &dragger, false, true, false);
  696.                 if(!EqualRect(&origRect,&dragger)){
  697.                     /* if it really moved, update the dirty flag  <ckh 1.0.2>*/                    
  698.                     (*tempWC)->windowDirty = kMyTrue;
  699.                     }
  700.                 *((Rect *)(*(*tempPicRect)))=dragger;
  701.                 InvalRect(&dragger);
  702.                 InvalRect(&origRect);                
  703.                 if ((*tempWC)->hasSelection)        
  704.                     InvalRect(&(*tempWC)->selectionRect);
  705.                 (*tempWC)->hasSelection = true;
  706.                 (*tempWC)->selectionRect = dragger;
  707.                 /* make this one pixel bigger, so if the user wants to publish a Pict */
  708.                 /* they get the whole thing */
  709.                 InsetRect(&(*tempWC)->selectionRect,-1,-1);
  710.                 break;
  711.                 
  712.                 
  713.             }
  714.             tempPicRect += 1;
  715.         }
  716.         HUnlock((*tempWC)->pictRects);
  717.         
  718.     }
  719.     if (!hadIt) {
  720.         /* check all my shapes */
  721.         if ((*tempWC)->numShapes) {
  722.             Boolean offsetIt = false;
  723.             theShapes = (*tempWC)->theShapes;
  724.             do {
  725.                 Rect dragger;
  726.                 HLock((Handle)theShapes);
  727.                 dragger = (*theShapes)->theRect;
  728.                 if ((*theShapes)->type == kLineShape) {
  729.                     short temp;
  730.                     
  731.                     if (dragger.top > dragger.bottom) {
  732.                         offsetIt = true;
  733.                         temp = dragger.top;
  734.                         dragger.top = dragger.bottom;
  735.                         dragger.bottom = temp;
  736.                     }
  737.                     if (dragger.left > dragger.right) {
  738.                         offsetIt = true;
  739.                         temp = dragger.left;
  740.                         dragger.left = dragger.right;
  741.                         dragger.right = temp;
  742.                         
  743.                     }
  744.                 }
  745.                 if (PtInRect(*where, &dragger)) {                    
  746.                     thePoint = *where;                    
  747.                     /* have to see if this was a line, since that rect may be reversed */                    
  748.                     origRect = dragger;
  749.                     InsetRect(&dragger, -1, -1);
  750.                     hadIt = true;
  751.                     PullRect(tempWC, &dragger, false, true, false);
  752.                     InsetRect(&dragger, 1, 1);
  753.                     if(!EqualRect(&origRect,&dragger))(*tempWC)->windowDirty = kMyTrue;
  754.                     if (offsetIt) {
  755.                         OffsetRect(&(*theShapes)->theRect, dragger.left - origRect.left, dragger.top - origRect.top);
  756.                     } else {
  757.                         (*theShapes)->theRect = dragger;
  758.                     }
  759.                     InvalRect(&dragger);
  760.                     InvalRect(&origRect);
  761.                     
  762.                     (*tempWC)->hasSelection = true;
  763.                     if ((*tempWC)->hasSelection)
  764.                         InvalRect(&(*tempWC)->selectionRect);
  765.                     (*tempWC)->hasSelection = true;
  766.                     (*tempWC)->selectionRect = dragger;                    
  767.                     /* make this one pixel bigger, so if the user wants to publish an object */
  768.                     /* they get the whole thing */
  769.                     InsetRect(&(*tempWC)->selectionRect,-1,-1);
  770.                     break;
  771.                     
  772.                     
  773.                     
  774.                 }
  775.                 
  776.                 HUnlock((Handle)theShapes);
  777.                 theShapes = (*theShapes)->nextShape;
  778.             }while (theShapes); /* end of shapes */
  779.             
  780.         }
  781.     }
  782. } /* end DragPictOrObject */
  783.  
  784. /* KillSelection removes any selection from the current window */
  785. void KillSelection(windowCHandle tempWC)
  786. {
  787.     Rect nulRect =  {
  788.         0, 0, 0, 0
  789.     };
  790.     
  791.     InvalRect(&(*tempWC)->selectionRect);
  792.     (*tempWC)->selectionRect = nulRect;
  793.     (*tempWC)->hasSelection = false;
  794.     
  795. } /* end KillSelection */
  796.  
  797. /* UndoLast undoes the last drawing action that happened in the current 
  798. * window.  Each window has it's own record of the last action, so 
  799. * Undo is always valid for the current window, and will not act on a 
  800. * window the user doesn't expect. */
  801. void UndoLast(void)
  802. {
  803.     windowCHandle temp;
  804.     WindowPtr tempPort;
  805.     ShapesHandle tempSH, beforeLast;
  806.     GetPort(&tempPort);                                     /* not really necessary, but I'm paranoid */
  807.     SetPort(FrontWindow());
  808.     temp = (windowCHandle)GetWRefCon(FrontWindow());
  809.     HLock((Handle)temp);                                    /* memory may move when handles are resized */
  810.     switch ((*temp)->undoAction) {                          /* last action that happened in this window */
  811.         /* For the graphic objects, we need to erase the last thing draw and update
  812.         * the window record's handles and counts */
  813.         case kDrawLine:
  814.         case kDrawRect:
  815.         case kDrawOval:
  816.             /* unlink and dispose of the last shape handle please */
  817.             /* find the last shape */
  818.             beforeLast = (*temp)->theShapes;
  819.             tempSH = (*temp)->theShapes;
  820.             if ((*temp)->numShapes == 1) {
  821.                 (*temp)->numShapes = 0;
  822.                 DisposeHandle((Handle)(*temp)->theShapes);
  823.                 (*temp)->theShapes = nil;
  824.             } else {
  825.                 register qq;
  826.                 for (qq = 0; qq < (*temp)->numShapes - 2; qq++) {
  827.                     tempSH = (*tempSH)->nextShape;
  828.                 }
  829.                 DisposeHandle((Handle)(*tempSH)->nextShape);
  830.                 (*tempSH)->nextShape = nil;
  831.                 (*temp)->numShapes--;
  832.                 
  833.             }
  834.             break;
  835.         case kTextBox:
  836.             TEDispose((*temp)->boxHandle);
  837.             (*temp)->boxHandle = nil;
  838.             InsetRect(&(*temp)->textBox, -3, -2);           /* just don't ask */
  839.             InvalRect(&(*temp)->textBox);
  840.             break;
  841.         case kSelectStuff:
  842.             KillSelection(temp);
  843.             break;
  844.         case kMoveObject:
  845.             
  846.             break;
  847.     }
  848.     HUnlock((Handle)temp);
  849.     /* now make sure things get refreshed */
  850.     InvalRect(&(FrontWindow()->portRect));
  851.     EraseRect(&(FrontWindow()->portRect));
  852.     SetUndo(0, false);
  853.     SetPort(tempPort);
  854. } /* end UndoLast */
  855.  
  856. /* AddLine adds a line to our window data structure */
  857. /* nowHandle is the window data structure handle */
  858. /* inLine is the line to add */
  859. void AddLine(windowCHandle nowHandle, myLine *inline)
  860. {Rect tempRect;
  861.   short temp;
  862. ShapesHandle newShape = NewShape(nowHandle);
  863.  
  864. (*newShape)->type=kLineShape;
  865. (*newShape)->aeType = cGraphicLine;
  866. (*newShape)->theRect.top =  inline->start.v;
  867. (*newShape)->theRect.left = inline->start.h;
  868. (*newShape)->theRect.bottom = inline->end.v;
  869. (*newShape)->theRect.right = inline->end.h;
  870.  
  871. tempRect = (*newShape)->theRect;
  872. if (tempRect.top > tempRect.bottom) {
  873.  
  874. temp = tempRect.top;
  875. tempRect.top = tempRect.bottom;
  876. tempRect.bottom = temp;
  877. }
  878. if (tempRect.left > tempRect.right) {
  879.  
  880. temp = tempRect.left;
  881. tempRect.left = tempRect.right;
  882. tempRect.right = temp;
  883.  
  884. }
  885.  
  886. InvalRect(&tempRect);
  887. }
  888.  
  889. /* end AddLine */
  890.  
  891. /* AddRect adds a rectangle  to our window data structure */
  892. /* nowHandle is the window data structure handle */
  893. /* inRect is the rect to add */
  894. void AddRect(windowCHandle nowHandle, Rect *inrect)
  895. {ShapesHandle tempShape = NewShape(nowHandle);
  896. (*tempShape)->type=kRectShape;
  897. (*tempShape)->aeType = cRectangle;
  898. (*tempShape)->theRect=*inrect;
  899. InvalRect(inrect);
  900. }
  901.  
  902. /* end AddRect */
  903.  
  904. /* AddTextBox adds a text editing box to our window data structure */
  905. /* nowHandle is the window data structure handle */
  906. /* inRect is the position to put the box in to add */
  907.  
  908. void AddTextBox(windowCHandle nowHandle, Rect *inrect)
  909. {
  910.     Rect framer;
  911.     HLock((Handle)nowHandle);
  912.     
  913.     (*nowHandle)->textBox = *inrect;
  914.     (*nowHandle)->windowDirty = kMyTrue;
  915.     /* Create a TERecord to go here */
  916.     InsetRect(&(*nowHandle)->textBox, -3, -3);
  917.     (*nowHandle)->boxHandle = TENew(inrect, &(*nowHandle)->textBox);
  918.     TEActivate((*nowHandle)->boxHandle);
  919.     framer = (*nowHandle)->textBox;
  920.     InsetRect(&framer, -3, -2);
  921.     InvalRect(&framer);
  922.     HUnlock((Handle)nowHandle);
  923. }
  924.  
  925. /* end AddTextBox */
  926.  
  927. /* AddOval adds a oval  to our window data structure */
  928. /* nowHandle is the window data structure handle */
  929. /* inOval is the oval to add */
  930. void AddOval(windowCHandle nowHandle, Rect *inoval)
  931. {ShapesHandle tempShape = NewShape(nowHandle);
  932. (*tempShape)->type=kOvalShape;
  933. (*tempShape)->aeType = cOval;
  934. (*tempShape)->theRect=*inoval;
  935. InvalRect(inoval);
  936. } /* end AddOval */
  937.  
  938. /* AddSelection adds a selection rectangle  to our window data structure */
  939. /* nowHandle is the window data structure handle */
  940. /* inRect is the rect to add */
  941. void AddSelection(windowCHandle nowHandle, Rect *inrect)
  942. {
  943.     HLock((Handle)nowHandle);
  944.     (*nowHandle)->selectionRect = *inrect;
  945.     (*nowHandle)->hasSelection = true;
  946.     HUnlock((Handle)nowHandle);
  947. } /* end AddSelection */
  948.  
  949.  
  950. /* NewShape adds a new shape to our window structure */
  951.  
  952. ShapesHandle NewShape(windowCHandle theWindow)
  953. {
  954. ShapesHandle newShape = (ShapesHandle)NewHandle(sizeof(Shapes));
  955. ShapesHandle tempShapes=(*theWindow)->theShapes;
  956. (*newShape)->theColor = gColorArray[gCurrentColor];
  957. if(tempShapes){ /* if there is already a shape defined */
  958. /* find the end and store this handle there */
  959. while((*tempShapes)->nextShape){
  960. tempShapes=(*tempShapes)->nextShape;
  961. }
  962. (*tempShapes)->nextShape=newShape;
  963. } else {
  964. /* first shape */
  965. (*theWindow)->theShapes=newShape;
  966. }
  967. /* increase our count of shapes */
  968. (*theWindow)->numShapes++;
  969. (*theWindow)->windowDirty = kMyTrue;
  970. (*newShape)->nextShape=nil;
  971. return(newShape);
  972. }
  973. /* end NewShape */
  974.  
  975.  
  976.  
  977.  
  978. /* ChangePlane does the housekeeping we need to do when a window comes to */
  979. /* the front, swapping menu checks, setting the cursor, and so on */
  980. /* And by the way, this routine has caused me more problems than any other, I will */
  981. /* be completely rewriting it in the next release, it is _not_ optimal. */
  982. void ChangePlane(WindowPtr twindow)
  983. {
  984.     short temp;
  985.     Rect scratchRect;
  986.     WindowPtr oldWindow = FrontWindow();
  987.     windowCHandle shortname;
  988.     /* Before the swap kill any current borders */
  989.     DeBorderSelection();
  990.      
  991.     /* deactivate the textedit record of the old window, if there is one */
  992.     if (oldWindow != nil && oldWindow != twindow && IsMyWindow(oldWindow)) {
  993.         windowCHandle tempCH = (windowCHandle)GetWRefCon(oldWindow);
  994.         if ((*tempCH)->boxHandle != nil)
  995.             TEDeactivate((*tempCH)->boxHandle);
  996.             SetPort(oldWindow);
  997.             scratchRect = twindow->portRect;
  998.     scratchRect.top = scratchRect.bottom - 15;
  999.     scratchRect.left = scratchRect.right - 15;
  1000.     InvalRect(&scratchRect);
  1001.  
  1002.     }
  1003.     /* if the window coming forward isn't a doc window, dim the tools menu */
  1004.  
  1005.     if (((WindowPeek)twindow)->windowKind != kDocumentWindow) {
  1006.         SetWMenus(false);
  1007.     } else {
  1008.         SetWMenus(true);
  1009.     }
  1010.  
  1011.     SetUndo(0, true);                                       /* tell SetUndo to pull the undo item value out of the current record */
  1012.     shortname = (windowCHandle)GetWRefCon(twindow);         /* was oldwindow */
  1013.     HLock((Handle)shortname);
  1014.     temp = (*shortname)->currentAction;                     /* pull the last action the */
  1015.     HUnlock((Handle)shortname);                             /* user was performing out of the */
  1016.     SetCurAction(temp);                                     /* window record */
  1017.     SetMyCursor(actsToIDs[temp]);                           /* set the right cursor */
  1018.     SwitchChecks(actsToIDs[temp]);                          /* check the right menu item */
  1019.     gShowPub = gShowSub = false;                            /* selections go away when windows */
  1020.     gShowingSecHandle = nil;
  1021.     if ((*shortname)->boxHandle != nil)
  1022.         TEActivate((*shortname)->boxHandle);
  1023.     SelectWindow(twindow);                                  /* select the window */
  1024.     SetPort(twindow);
  1025.     scratchRect = twindow->portRect;
  1026.     scratchRect.top = scratchRect.bottom - 15;
  1027.     scratchRect.left = scratchRect.right - 15;
  1028.     InvalRect(&scratchRect);
  1029.     /* and re-do our window indexes */
  1030.     /* •••• NOTE:  I am not including the AEStatus window in this  */    
  1031.     /* window index or check!  The AEStatus window is a special diagnostic
  1032.     /* only type window that is _not_ anything a 'real' application would have */
  1033.     /*  It can change planes in  the middle of an AppleEvent if there is information */
  1034.     /* to display, and if I included it in my real window list that */
  1035.     /* would violate 'state freezing' for the space of an event, which  */
  1036.     /* is A Bad Thing */
  1037.     /* So I'm looking at everything but the AES window */
  1038.     temp = 1;
  1039.     oldWindow = FrontWindow();
  1040.     while(oldWindow){
  1041.     shortname = (windowCHandle)GetWRefCon(oldWindow);
  1042.     if((((WindowPeek)oldWindow)->visible) && (((WindowPeek)oldWindow)->windowKind != kAEStatusWindow && IsMyWindow(oldWindow)))
  1043.     {(*shortname)->windowIndex = temp;
  1044.         temp++;}
  1045.     oldWindow = (WindowPtr)((WindowPeek)oldWindow)->nextWindow;
  1046.     }
  1047.     /* now any invisible windows, since their index will be after the visible ones */
  1048.     oldWindow = (WindowPtr)LMGetWindowList();
  1049.     while(oldWindow){
  1050.     shortname = (windowCHandle)GetWRefCon(oldWindow);
  1051.     if((!((WindowPeek)oldWindow)->visible) && (((WindowPeek)oldWindow)->windowKind != kAEStatusWindow) && IsMyWindow(oldWindow))
  1052.     {(*shortname)->windowIndex = temp;
  1053.     temp++;}
  1054.         oldWindow = (WindowPtr)((WindowPeek)oldWindow)->nextWindow;
  1055.     }
  1056. AdjustCursor(gERecord.where, mousergn);
  1057. }
  1058.  
  1059. /* end ChangePlane */
  1060.  
  1061. /* may be a shape ,PICT, or a selection range */
  1062. /* so if it's a shape, I cut the shape definition, pict, same thing.  */
  1063. /* if it's  a selection range, I dunno what I'm gonna do. */
  1064. /* no, actually I'll just cut all the components of the range */
  1065. void CutGraphic(windowCHandle tempWC)
  1066. {Rect localSelection = (*tempWC)->selectionRect;
  1067.  
  1068.  
  1069. }
  1070.  
  1071. void CopyGraphic(windowCHandle tempWC)
  1072. {
  1073. #pragma unused (tempWC)
  1074. }
  1075. void ClearGraphic(windowCHandle tempWC)
  1076. {
  1077. #pragma unused (tempWC)
  1078. }
  1079.  
  1080.  
  1081. /* This sets window properties, it's passed one of our property tokens */
  1082. OSErr SetWindowProperty(PropertyTHdl propertyBack, AEDesc *theData)
  1083. {
  1084.     OSErr myErr = noErr;
  1085.     AEDesc convertedDesc;
  1086.     Size dataSize;
  1087.     switch ((*propertyBack)->theProperty) {
  1088.         case pName:
  1089.             /* setting name.  Let's see if the data is typeChar */
  1090.             if (theData->descriptorType != typeChar) {
  1091.                 /* problem.  See if it'll coerce */
  1092.                 myErr = AECoerceDesc(theData, typeChar, &convertedDesc);
  1093.                 if (!myErr) {
  1094.                     /* it converted.  swap descs (kinda) */
  1095.                     myErr = AEDisposeDesc(theData);
  1096.                     myErr = AEDuplicateDesc(&convertedDesc, theData);
  1097.                     myErr = AEDisposeDesc(&convertedDesc);
  1098.                 }
  1099.             }
  1100.             if (!myErr) {
  1101.                 Str63 newName,oldName;
  1102.                 
  1103.                 /* the data in the handle is text.  Make it into a string for us */
  1104.                 dataSize = GetHandleSize(theData->dataHandle);
  1105.                 if (dataSize > 63)
  1106.                     dataSize = 63;                          /* Truncating the name because I want to */
  1107.                 HLock(theData->dataHandle);
  1108.                 BlockMove((Ptr)*(theData->dataHandle), (Ptr)&newName[1], dataSize);
  1109.                 HUnlock(theData->dataHandle);
  1110.                 newName[0] = dataSize;
  1111.                 /* set the title.  We have the window pointer in the property token */
  1112.                 GetWTitle((*propertyBack)->token.window,&oldName);
  1113.                 SetWTitle((*propertyBack)->token.window, &newName);
  1114.             /* v 1.0.1 revise old name in window menu please */
  1115.                 AddToWindowMenu((*propertyBack)->token.window,&oldName);
  1116.                 /* all done! */
  1117.             }
  1118.             break;
  1119.         case pBounds:
  1120.             /* we have been passed a new rectangle, in global coords */
  1121.             /* so pull the rectangle out */
  1122.             /* again, make sure the data is in a rect type */
  1123.             if (theData->descriptorType != typeQDRectangle) {
  1124.                 /* problem.  See if it'll coerce */
  1125.                 myErr = AECoerceDesc(theData, typeQDRectangle, &convertedDesc);
  1126.                 if (!myErr) {
  1127.                     /* it converted.  swap descs (kinda) */
  1128.                     myErr = AEDisposeDesc(theData);
  1129.                     myErr = AEDuplicateDesc(&convertedDesc, theData);
  1130.                     myErr = AEDisposeDesc(&convertedDesc);
  1131.                 }
  1132.             }
  1133.             if (!myErr) {
  1134.                 Rect newRect;
  1135.                 /* OK, the data handle contains a rect.  I'll move it so it's easier to read */
  1136.                 newRect = *((Rect *)*(theData->dataHandle));
  1137.                 /* Move the window.  Pass a false as BringToFront since we don't want window shuffling */
  1138.                 /* check the rect for validity */
  1139.                 if( newRect.top < newRect.bottom && newRect.left < newRect.right){
  1140.                 MoveWindow((*propertyBack)->token.window, newRect.left, newRect.top, false);
  1141.                 /* set the new dimensions.  And generate an update as needed */
  1142.                 SizeWindow((*propertyBack)->token.window, (newRect.right - newRect.left), (newRect.bottom - newRect.top), true);
  1143.                 /* Done! */
  1144.                 } else {
  1145.                 myErr = errAEEventNotHandled;
  1146.                 AddToReply("\pBad Window Size",kWeirdSizeErr);
  1147.                 }
  1148.             }
  1149.             break;
  1150.         case pHasTitleBar:
  1151.         case pIsModal:
  1152.         case pIsModified:
  1153.         case pIsResizable:
  1154.         case pIsStationeryPad:
  1155.         case pIsZoomed:
  1156.         /* add new Winter '92 registry error code <ckh 1.0.2>*/
  1157.             myErr = errAENotModifiable;                   /* I am not allowing these properties to be modified */
  1158.             AddToReply("\p Attempted to modify a read-only parameter",errAENotModifiable);
  1159.  
  1160.             break;
  1161.         case pVisible:
  1162.             /* value is true oder false */
  1163.  
  1164.  
  1165.             if(**(theData->dataHandle)){
  1166.                 ShowWindow((*propertyBack)->token.window);
  1167.                 AddToWindowMenu((*propertyBack)->token.window,nil);
  1168.                 }
  1169.             else {
  1170.                 DeleteFromWindowMenu((*propertyBack)->token.window);
  1171.                 HideWindow((*propertyBack)->token.window);
  1172.                 }
  1173.  
  1174.             break;
  1175.     }
  1176.     return(myErr);
  1177. } /* end SetWindowProperty */
  1178.  
  1179. OSErr SetShapeProperty(PropertyTHdl propertyBack, AEDesc *theData)
  1180. {
  1181.     OSErr myErr = noErr;
  1182.     AEDesc convertedDesc;
  1183.     WindowPtr tempWindow;
  1184.     ShapesHandle theShape =(*propertyBack)->token.shapeHandle;
  1185.     switch ((*propertyBack)->theProperty) {
  1186.         case pBounds:
  1187.         case pDefinitionRect:
  1188.             /* we have been passed a new rectangle */
  1189.             /* so pull the rectangle out */
  1190.             /* again, make sure the data is in a rect type */
  1191.             if (theData->descriptorType != typeQDRectangle) {
  1192.                 /* problem.  See if it'll coerce */
  1193.                 myErr = AECoerceDesc(theData, typeQDRectangle, &convertedDesc);
  1194.                 if (!myErr) {
  1195.                     /* it converted.  swap descs (kinda) */
  1196.                     myErr = AEDisposeDesc(theData);
  1197.                     myErr = AEDuplicateDesc(&convertedDesc, theData);
  1198.                     myErr = AEDisposeDesc(&convertedDesc);
  1199.                 }
  1200.             }
  1201.             if (!myErr) {
  1202.             /* we have a rect.  Set the shape to it */
  1203.             HLock((Handle)theShape);
  1204.             /* invalidate the old rect so the user sees the change */
  1205.             /* • NOTE:  I'm getting current port and setting the one in the  */
  1206.             /* token.  Remember, there is NO reason for an event to have to */
  1207.             /* occur in the frontmost or current port */
  1208.             GetPort(&tempWindow);
  1209.             SetPort((*propertyBack)->inWindow);
  1210.             InvalRect(&(*theShape)->theRect);
  1211.             /* i dont want the rect set to zero, please */
  1212.             if(!EmptyRect(((Rect *)*(theData->dataHandle)))){
  1213.             
  1214.             (*theShape)->theRect = *((Rect *)*(theData->dataHandle));
  1215.             InvalRect(&(*theShape)->theRect);}
  1216.             SetPort(tempWindow);
  1217.             }
  1218.             break;
  1219.         case pPenColor:
  1220.         /* pretty much the same for colors */
  1221.            if (theData->descriptorType != typeRGBColor) {
  1222.                 /* problem.  See if it'll coerce */
  1223.                 myErr = AECoerceDesc(theData, typeRGBColor, &convertedDesc);
  1224.                 if (!myErr) {
  1225.                     /* it converted.  swap descs (kinda) */
  1226.                     myErr = AEDisposeDesc(theData);
  1227.                     myErr |= AEDuplicateDesc(&convertedDesc, theData);
  1228.                     myErr |= AEDisposeDesc(&convertedDesc);
  1229.                 }
  1230.             }
  1231.             if (!myErr) {
  1232.             /* we have a rect.  Set the shape to it */
  1233.             HLock((Handle)theShape);
  1234.             /* invalidate the old rect so the user sees the change */
  1235.             /* • NOTE:  I'm getting current port and setting the one in the  */
  1236.             /* token.  Remember, there is NO reason for an event to have to */
  1237.             /* occur in the frontmost or current port */
  1238.             GetPort(&tempWindow);
  1239.             SetPort((*propertyBack)->inWindow);
  1240.             InvalRect(&(*theShape)->theRect);
  1241.             (*theShape)->theColor = *((RGBColor *)*(theData->dataHandle));
  1242.             SetPort(tempWindow);
  1243.             }
  1244.         
  1245.         
  1246.         break;
  1247.         /* I'm not handling any other properties right now, check again later */
  1248.         default:
  1249.         /* add new Winter '92 registry error code <ckh 1.0.2>*/
  1250.             myErr = errAENotModifiable;                   /* I am not allowing these properties to be modified */
  1251.             AddToReply("\p Attempted to modify a read-only parameter",errAENotModifiable);
  1252.  
  1253.         break;
  1254.     }
  1255.     return(myErr);
  1256. }
  1257.  
  1258.  
  1259.  
  1260.  
  1261. /* Check to see if a window belongs to a desk accessory. */
  1262. /* This is _almost_ unnecessary in System 7.  Since DAs have their own layer now, and */
  1263. /* it's _almost_ impossible to force a DA into an applications space, this should */
  1264. /* rarely be true */
  1265. /* HOWEVER, there are INITs out there that will stick windows in your window list. */
  1266. /* BallooonWriter does, for example */
  1267. Boolean IsDAWindow(WindowPtr window)
  1268. {
  1269.     if (window == nil)
  1270.         return false;
  1271.     else                                                    /* DA windows have negative windowKinds */
  1272.         return((WindowPeek)window)->windowKind < 0;
  1273. }
  1274.  
  1275. /* end IsDAWindow*/
  1276.  
  1277. /* DrawClip draws the current contents of the clipboard */
  1278. void DrawClip(windowCHandle theWind, WindowPtr windowIn)
  1279. {
  1280. #pragma unused(theWind)
  1281.     RgnHandle tempRgn;
  1282.     Rect theRect;
  1283.     Str63 clipString;
  1284.     UpdateScrap(false);                                     /* no neverending updateas */
  1285.     MoveTo(10, 10);
  1286.     /* Get the basic clipboard text */
  1287.     GetIndString(clipString, kClipBoardStrings, 1);
  1288.     DrawString(clipString);
  1289.     /* get the string that says what type of thing is on the clipboard */
  1290.     GetIndString(clipString, kClipBoardStrings, gClipHasContents);
  1291.     DrawString(clipString);
  1292.     MoveTo(0, 13);
  1293.     /* underline those words */
  1294.     LineTo(FindClipWindow()->portRect.right, 13);
  1295.     HLock(gScrapData);
  1296.     /* I make all my clipboard data into a picture, so we can use DrawPicture to display it */
  1297.     if ((GetHandleSize(gScrapData) != 0) && gScrapData) {
  1298.         Rect picRect;
  1299.         picRect = ((*(PicHandle)gScrapData))->picFrame;
  1300.         OffsetRect(&picRect, 0, 15);
  1301.         DrawPicture((PicHandle)gScrapData, &picRect);
  1302.     }
  1303.     HUnlock(gScrapData);
  1304.     /* Add our grow box, clip out the rect so we don't get the */
  1305.     /* spurious scroll area lines */
  1306.     theRect = windowIn->portRect;
  1307.     theRect.top = theRect.bottom - 15;
  1308.     theRect.left = theRect.right - 15;
  1309.     tempRgn = NewRgn();
  1310.     GetClip(tempRgn);
  1311.     ClipRect(&theRect);
  1312.     DrawGrowIcon(windowIn);
  1313.     SetClip(tempRgn);
  1314.     DisposeRgn(tempRgn);
  1315.     
  1316. } /* end DrawClip */
  1317.  
  1318.  
  1319.  
  1320. void ClipClick(WindowPtr twindow)
  1321. {                                                           /* nothing happens on a clipboard click, it's in here for whenever I put scroll bars in */
  1322. #pragma unused (twindow)
  1323. } /* end ClipClick */
  1324.  
  1325. /* Closes the clipboard window and takes it off the window menu */
  1326. /* Remember, however, it isn't dead.  If there is a section on the  */
  1327. /* clipboard it can still get updated */
  1328. void CloseClip(WindowPtr inWind)
  1329. {
  1330. #pragma unused (inWind)
  1331.     WindowPtr clipWind = FindClipWindow();
  1332.     Str63 menuText;
  1333.     if (((WindowPeek)clipWind)->visible) {
  1334.             HideWindow(clipWind);
  1335.         
  1336.         DeleteFromWindowMenu(clipWind);
  1337.         if (FrontWindow() != nil)
  1338.             ChangePlane(FrontWindow());
  1339.         /* change the menu string to read 'Show Clipboard' */
  1340.         GetIndString(menuText, kGeneralStrings, kShowClipString);
  1341.         SetMenuItemText(gEditMenuHandle, kClapNum, menuText);
  1342.     }
  1343. } /* end CloseClip */
  1344.  
  1345. void SizeClip(WindowPtr windowIn)
  1346. {
  1347. #pragma unused (windowIn)
  1348. } /* end SizeClip */
  1349.  
  1350. /* UpdateScrap reads in the current scrap, and makes a picture from it */
  1351. /* It will also cause the clipboard window to redraw if it's visible */
  1352. void UpdateScrap(Boolean refreshIt)
  1353. {
  1354.     /* The 'refreshIt' variable is there to indicate if the window should be */
  1355.     /* invalidated or not.  I added this so this routine can safely */
  1356.     /* be called from the drawing procedure without fear of nverending updates */
  1357.     Handle textData;
  1358.     long myOffset;
  1359.     long length;
  1360.     textData = NewHandle(0);
  1361.     if (gClipHasContents == kClipHasSub) {
  1362.     } else {
  1363.         /* show standard scrap types, prefering pictures */
  1364.         length = GetScrap(gScrapData, 'PICT', &myOffset);
  1365.         if (length < 0) {
  1366.             if (length == noTypeErr) {
  1367.                 length = GetScrap(textData, kGenericTEXTWord, &myOffset);
  1368.                 /* if it's text, I'm going to make it into a picture for my clipboard display, makes things */
  1369.                 /* easier in my draw proc */
  1370.                 if (length > 0) {
  1371.                     DisposeHandle(gScrapData);               /* kill the old one */
  1372.                     gScrapData = (Handle)OpenPicture(&FindClipWindow()->portRect);
  1373.                     HLock(textData);
  1374.                     TETextBox(*textData, length, &(FindClipWindow())->portRect, teJustLeft);
  1375.                     HUnlock(textData);
  1376.                     ClosePicture();
  1377.                     gClipHasContents = kClipHasText;
  1378.                 }
  1379.             } else {                                        /* another type of error, like nothing available at all */
  1380.                 MySetHandleSize(gScrapData, 0);
  1381.                 gClipHasContents = kClipEmpty;
  1382.             }
  1383.         } else {
  1384.             /* set the pict rect so it's in the upper left of our clipboard */
  1385.             gClipHasContents = kClipHasPict;
  1386.             OffsetRect(&((*(PicHandle)gScrapData))->picFrame, (((*(PicHandle)gScrapData))->picFrame.left * -1),
  1387.                        (((*(PicHandle)gScrapData))->picFrame.top * -1) + 11);
  1388.         }
  1389.     }
  1390.     DisposeHandle(textData);
  1391.     if (refreshIt && ((WindowPeek)FindClipWindow())->visible) {
  1392.         /* if we want it refreshed, force an update */
  1393.         WindowPtr temp;
  1394.         GetPort(&temp);
  1395.         SetPort(FindClipWindow());
  1396.         InvalRect(&(FindClipWindow())->portRect);
  1397.         SetPort(temp);
  1398.     }
  1399. }
  1400.  
  1401. /* end updatescrap */
  1402.  
  1403. /* SpitClip spits our private subscription out to the general clipboard as a PICT type scrap */
  1404. /* when we go in the background.  Does nothing if it's not a subscription, since it'll already */
  1405. /* be right. */
  1406.  
  1407. void SpitClip(void)
  1408. {
  1409.     if (gClipHasContents == kClipHasSub) {
  1410.         ZeroScrap();
  1411.         HLock(gScrapData);
  1412.         PutScrap(GetHandleSize(gScrapData), 'PICT', *gScrapData);
  1413.         
  1414.     }
  1415. } /* end spitclip */
  1416.  
  1417. /* Handy little routine to find and return a pointer to the clipboard, visible or not */
  1418. WindowPtr FindClipWindow(void)
  1419. {
  1420.     WindowPtr twindow = (WindowPtr)LMGetWindowList();
  1421.     while (twindow) {
  1422.         if (((WindowPeek)twindow)->windowKind == kClipboardWindow)
  1423.             return(twindow);
  1424.         twindow = (WindowPtr)((WindowPeek)twindow)->nextWindow;
  1425.     } /* end of windows while */
  1426.     return(nil);                                            /* should never reach here */
  1427. } /* end FindClipWindow */
  1428.  
  1429. /* AppleEvent Status Window routines */
  1430. /* Changes the visiblility state of the AEStatus window */
  1431. void ToggleAEWindow(void)
  1432. {
  1433.     WindowPtr oldFront = FrontWindow();
  1434.     Str63 menuText;
  1435.     short tempShort;
  1436.     if(!IsModalFront()){
  1437.     WindowPtr AEWind = FindAEWindow();                      /* find it */
  1438.     if (((WindowPeek)AEWind)->visible) {                    /* if it's visiblem hide it */
  1439.         HideWindow(AEWind);
  1440.         DeleteFromWindowMenu(AEWind);                       /* and remive it from the menu */
  1441.         tempShort = kShowAEString;
  1442.     } else {
  1443.         ShowWindow(AEWind);                                 /* show the thing */
  1444.         AddToWindowMenu(AEWind, nil);                       /* add it's name to the window menu */
  1445.         if(oldFront)ChangePlane(AEWind);                                /* bring it forward */
  1446.         tempShort = kHideAEString;
  1447.         
  1448.     }
  1449.     /* get the correct text for the 'Show/Hide AEWindow' menu item */
  1450.     GetIndString(menuText, kGeneralStrings, tempShort);
  1451.     SetMenuItemText(gAppleEventMenuHandle, kShowAEWind, menuText);
  1452. }
  1453. } /* end ToggleAEWindow */
  1454.  
  1455. /* Handy little routine for finding the AEStatus window, visible or not */
  1456. WindowPtr FindAEWindow(void)
  1457. {
  1458.     WindowPtr twindow = (WindowPtr)LMGetWindowList();
  1459.     while (twindow) {
  1460.         if (((WindowPeek)twindow)->windowKind == kAEStatusWindow)
  1461.             return(twindow);
  1462.         twindow = (WindowPtr)((WindowPeek)twindow)->nextWindow;
  1463.     }
  1464.     return(nil);                                            /* should never reach here */
  1465.     
  1466. } /* end FindAEWindow */
  1467.  
  1468. /* Draws the AEStatus window */
  1469. void DrawAES(windowCHandle theWind, WindowPtr windowIn)
  1470. {
  1471.     Rect theRect;
  1472.     RgnHandle tempRgn;
  1473.     theRect = windowIn->portRect;
  1474.     TEUpdate(&theRect, (*theWind)->boxHandle);
  1475.     theRect.top = theRect.bottom - 15;
  1476.     theRect.left = theRect.right - 15;
  1477.     tempRgn = NewRgn();
  1478.     GetClip(tempRgn);
  1479.     ClipRect(&theRect);
  1480.     DrawGrowIcon(windowIn);
  1481.     SetClip(tempRgn);
  1482.     DisposeRgn(tempRgn);
  1483.     
  1484. } /* end DrawAES */
  1485.  
  1486.  
  1487.  
  1488. /* Handles a click in the AEStatus window,  by  doing a TEClick */
  1489. void ClickAES(WindowPtr twindow)
  1490. {
  1491.     windowCHandle tempWCH = (windowCHandle)GetWRefCon(twindow);
  1492.     Rect theRect = twindow->portRect;
  1493.     SetPort(twindow);
  1494.     GlobalToLocal(&gERecord.where);
  1495.     
  1496.     TEClick(gERecord.where, gERecord.modifiers & shiftKey, (*tempWCH)->boxHandle);
  1497.     
  1498. } /* end ClickAES */
  1499.  
  1500. /* CloseAES doesn't close the window, just makes it invisible */
  1501. void CloseAES(WindowPtr inWind)
  1502. {
  1503. #pragma unused (inWind)
  1504. WindowPtr aeWind = FindAEWindow();
  1505.     Str32 menuText;
  1506.     if (((WindowPeek)aeWind)->visible) {               
  1507.         HideWindow(aeWind);
  1508.         DeleteFromWindowMenu(aeWind);
  1509.         if (FrontWindow() != nil)
  1510.             ChangePlane(FrontWindow());
  1511.         /* and change the menu text */
  1512.         GetIndString(menuText, kGeneralStrings, kShowAEString);
  1513.         SetMenuItemText(gAppleEventMenuHandle, kShowAEWind, menuText);
  1514.     }
  1515. } /* end CloseAES */
  1516.  
  1517. void AESKey(char theKey, windowCHandle tempWC)
  1518. {
  1519.     TEKey(theKey, (*tempWC)->boxHandle);
  1520. } /* end AESKey */
  1521.  
  1522. /* Resize the AES window */
  1523. /* When resizing TextEdit records, I always destroy and recreate them in */
  1524. /* their new size, instead of mucking around with the rects.  Simpler and safer */
  1525. void SizeAES(WindowPtr windowIn)
  1526. {
  1527.     Handle theText;
  1528.     Rect newRect;
  1529.     
  1530.     short selStart, selEnd;
  1531.     windowCHandle tempWCH = (windowCHandle)GetWRefCon(windowIn);
  1532.     /* recalculate the TE rectangle */
  1533.     newRect = windowIn->portRect;
  1534.     newRect.right -= 16;
  1535.     /* Get the old text */
  1536.     theText = (Handle)TEGetText((*tempWCH)->boxHandle);
  1537.     /* get the old selection range */
  1538.     selStart = (*(*tempWCH)->boxHandle)->selStart;
  1539.     selEnd = (*(*tempWCH)->boxHandle)->selEnd;
  1540.     /* copy the old text */
  1541.     HandToHand(&theText);
  1542.     /* kill the TERecord */
  1543.     TEDeactivate((*tempWCH)->boxHandle);
  1544.     TEDispose((*tempWCH)->boxHandle);
  1545.     /* recreate it in it's new size */
  1546.     (*tempWCH)->boxHandle = TENew(&newRect, &newRect);
  1547.     /* and do all the housekeeping associated with a new TERecord */
  1548.     TEAutoView(true, (*tempWCH)->boxHandle);
  1549.     HLock((Handle)theText);
  1550.     TESetText((Ptr)*theText, GetHandleSize((Handle)theText), (*tempWCH)->boxHandle);
  1551.     TECalText((*tempWCH)->boxHandle);
  1552.     DisposeHandle((Handle)theText);
  1553.     TEActivate((*tempWCH)->boxHandle);
  1554.     TESetSelect(selStart, selEnd, (*tempWCH)->boxHandle);
  1555.     TEUpdate(&newRect, (*tempWCH)->boxHandle);
  1556. } /* end SizeAES */
  1557.  
  1558. /* The next few routines add text to the AEStatus window, in various ways */
  1559. void AddToAEWindow(Ptr text, long count)
  1560. {
  1561.     WindowPtr tempW = FindAEWindow();
  1562.     WindowPtr temp;
  1563.     windowCHandle tempWCH = (windowCHandle)GetWRefCon(tempW);
  1564.     GetPort(&temp);
  1565.     /* No matter what, if we're adding text we want the window to be visible, even if  */
  1566.     /* it's not frontmost */
  1567.     if (!((WindowPeek)tempW)->visible) {
  1568.         ToggleAEWindow();
  1569.     
  1570.     }
  1571.     /* if it's your preference to see the window any time something happens, it comes forward here */
  1572.     if (gPreferences.bringAEUp && FrontWindow() != tempW && !IsModalFront())
  1573.         ChangePlane(tempW);                                 /* bring it forward if you want */
  1574.     SetPort(tempW);
  1575.     /* move to the end of the record */
  1576.     TESetSelect(32000, 32000, (*tempWCH)->boxHandle);
  1577.     /* add the text */
  1578.     TEInsert(text, count, (*tempWCH)->boxHandle);
  1579.     SetPort(temp);
  1580. } /* end AddToAEWindow */
  1581.  
  1582. /* routine to add a number easily */
  1583. void AddAENum(long theNum)
  1584. {
  1585.     Str31 theString;
  1586.     NumToString(theNum, theString);
  1587.     AddToAEWindow(&theString[1], theString[0]);
  1588.     
  1589. } /* end AddAENum */
  1590.  
  1591. /* routine to add a PString easily */
  1592. void AddAEText(ConstStr255Param theText)
  1593. {
  1594.     AddToAEWindow(&theText[1], theText[0]);
  1595.     
  1596. } /* end AddAEText */
  1597.  
  1598. /* This routine is called when the user selects a window from the Windows menu */
  1599. /* it gets the item text, then finds the window that matches it and */
  1600. /* makes it frontmost */
  1601. void WindowToFront(short which,Str63 name)
  1602. {
  1603.     Str63 tempTitle;
  1604.     Str63 otherName;
  1605.     WindowPtr frontW = FrontWindow();
  1606.     if (!frontW)
  1607.         return;
  1608.     if(name == nil){name = &otherName;
  1609.         GetMenuItemText(gWindowMenuHandle, which, name);
  1610.         }
  1611.     do {
  1612.         GetWTitle(frontW, tempTitle);
  1613.         if (EqualString(name, tempTitle, false, false)) {
  1614.             break;
  1615.         } else {
  1616.             frontW = (WindowPtr)((WindowPeek)frontW)->nextWindow;
  1617.         }
  1618.     }
  1619.             while (frontW);
  1620.  
  1621.     if (frontW)
  1622.         ChangePlane(frontW);
  1623.     
  1624. } /* end WindowToFront */
  1625.  
  1626. /* Adds the input window title to the window list.  If it was there  */
  1627. /* in an old incarnation, it replaces the old text with the new name */
  1628. /* (like when a user saves the file, or does a 'save as' */
  1629. void AddToWindowMenu(WindowPtr theWindow, const Str255 oldName)
  1630. {
  1631.     
  1632.     short count = CountMItems(gWindowMenuHandle);
  1633.     Str255 wTitle;
  1634.     Str255 theItem;
  1635.     short iCount = 0;
  1636.     GetWTitle(theWindow, wTitle);
  1637.     /* if the window already existed, change an existing menu item */
  1638.     if (oldName) {
  1639.         do {
  1640.             iCount++;
  1641.             GetMenuItemText(gWindowMenuHandle, iCount, theItem);
  1642.             if (EqualString(theItem, oldName, false, false))
  1643.                 break;
  1644.             
  1645.         }
  1646.                 while (true);
  1647.         SetMenuItemText(gWindowMenuHandle, iCount, wTitle);
  1648.     } else {
  1649.         count++;
  1650.         InsertMenuItem(gWindowMenuHandle, wTitle, count);
  1651.     }
  1652. } /* end AddToWindowMenu */
  1653.  
  1654. /* take this window off the window menu, for whatever reason */
  1655. void DeleteFromWindowMenu(WindowPtr theWindow)
  1656. {
  1657.     register qq;
  1658.     Str63 item, name;
  1659.     short count = CountMItems(gWindowMenuHandle);
  1660.     GetWTitle(theWindow, name);
  1661.     for (qq = 1; qq < count + 1; qq++) {
  1662.         GetMenuItemText(gWindowMenuHandle, qq, &item);
  1663.         if (EqualString(item, name, false, false)) {
  1664.             DeleteMenuItem(gWindowMenuHandle, qq);
  1665.         }
  1666.     }
  1667. } /* end DeleteFromWindowMenu */
  1668.  
  1669. /* CheckExisting is called from our file opener to see if this file */
  1670. /* is already open */
  1671. Boolean CheckExisting(FSSpecPtr newSpec)
  1672. {
  1673.     Boolean openNow = false;
  1674.     /* check against all the open windows */
  1675.     WindowPtr tempWindow = FrontWindow();
  1676.     FSSpec tempSpec;
  1677.     Boolean wasCh;
  1678.     windowCHandle tempWC;
  1679.     while(tempWindow){
  1680.         if(((WindowPeek)tempWindow)->windowKind == kDocumentWindow){
  1681.             tempWC = (windowCHandle)GetWRefCon(tempWindow);
  1682.             if(GetHandleSize((Handle)(*tempWC)->fileAliasHandle)){
  1683.                 ResolveAlias(nil,(*tempWC)->fileAliasHandle,&tempSpec,&wasCh);
  1684.                 openNow = CompareFSSpecs(&tempSpec,newSpec);
  1685.                 if(openNow)break;
  1686.             }
  1687.         
  1688.         }
  1689.         tempWindow = (WindowPtr)((WindowPeek)tempWindow)->nextWindow;
  1690.     }
  1691.     
  1692.     return(openNow);
  1693. } /* end CheckExisting */
  1694.  
  1695. #undef __MYWINDOWS__
  1696.